﻿using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

namespace Portal
{
    public class PDSASymmetric
    {
        private PDSAEncryptionType mbytEncryptionType;
        private SymmetricAlgorithm mCSP;
        private string mstrEncryptedString;
        private string mstrOriginalString;

        public PDSASymmetric()
        {
            this.mbytEncryptionType = PDSAEncryptionType.DES;
            this.SetEncryptor();
        }

        public PDSASymmetric(PDSAEncryptionType EncryptionType)
        {
            this.mbytEncryptionType = EncryptionType;
            this.SetEncryptor();
        }

        public PDSASymmetric(PDSAEncryptionType EncryptionType, string OriginalString)
        {
            this.mbytEncryptionType = EncryptionType;
            this.mstrOriginalString = OriginalString;
            this.SetEncryptor();
        }

        public PDSASymmetric(string key, string iv)
        {
            this.mbytEncryptionType = PDSAEncryptionType.DES;
            this.mstrOriginalString = this.OriginalString;
            this.SetEncryptor();
            this.KeyString = key;
            this.IVString = iv;
        }

        public PDSASymmetric(PDSAEncryptionType EncryptionType, string OriginalString, string key, string iv)
        {
            this.mbytEncryptionType = EncryptionType;
            this.mstrOriginalString = OriginalString;
            this.SetEncryptor();
            this.KeyString = key;
            this.IVString = iv;
        }

        public string Decrypt()
        {
            ICryptoTransform ct = this.mCSP.CreateDecryptor(this.mCSP.Key, this.mCSP.IV);
            byte[] byt = Convert.FromBase64String(this.mstrEncryptedString);
            MemoryStream ms = new MemoryStream();
            CryptoStream cs = new CryptoStream(ms, ct, CryptoStreamMode.Write);
            cs.Write(byt, 0, byt.Length);
            cs.FlushFinalBlock();
            cs.Close();
            this.mstrOriginalString = Encoding.UTF8.GetString(ms.ToArray());
            return this.mstrOriginalString;
        }

        public string Decrypt(string EncryptedString)
        {
            this.mstrEncryptedString = EncryptedString;
            return this.Decrypt();
        }

        public string Decrypt(string EncryptedString, PDSAEncryptionType EncryptionType, string key, string iv)
        {
            this.mstrEncryptedString = EncryptedString;
            this.mbytEncryptionType = EncryptionType;
            this.SetEncryptor();
            this.KeyString = key;
            this.IVString = iv;
            return this.Decrypt();
        }

        public string Encrypt()
        {
            ICryptoTransform ct = this.mCSP.CreateEncryptor(this.mCSP.Key, this.mCSP.IV);
            byte[] byt = Encoding.UTF8.GetBytes(this.mstrOriginalString);
            MemoryStream ms = new MemoryStream();
            CryptoStream cs = new CryptoStream(ms, ct, CryptoStreamMode.Write);
            cs.Write(byt, 0, byt.Length);
            cs.FlushFinalBlock();
            cs.Close();
            this.mstrEncryptedString = Convert.ToBase64String(ms.ToArray());
            return this.mstrEncryptedString;
        }

        public string Encrypt(string OriginalString)
        {
            this.mstrOriginalString = OriginalString;
            return this.Encrypt();
        }

        public string Encrypt(string OriginalString, PDSAEncryptionType EncryptionType)
        {
            this.mstrOriginalString = OriginalString;
            this.mbytEncryptionType = EncryptionType;
            return this.Encrypt();
        }

        public string Encrypt(string OriginalString, PDSAEncryptionType EncryptionType, string key, string iv)
        {
            this.mstrOriginalString = OriginalString;
            this.mbytEncryptionType = EncryptionType;
            this.SetEncryptor();
            this.KeyString = key;
            this.IVString = iv;
            return this.Encrypt();
        }

        public string GenerateIV()
        {
            this.mCSP.GenerateIV();
            return Convert.ToBase64String(this.mCSP.IV);
        }

        public string GenerateKey()
        {
            this.mCSP.GenerateKey();
            return Convert.ToBase64String(this.mCSP.Key);
        }

        private void SetEncryptor()
        {
            switch (this.mbytEncryptionType)
            {
                case PDSAEncryptionType.DES:
                    this.mCSP = new DESCryptoServiceProvider();
                    break;

                case PDSAEncryptionType.RC2:
                    this.mCSP = new RC2CryptoServiceProvider();
                    break;

                case PDSAEncryptionType.Rijndael:
                    this.mCSP = new RijndaelManaged();
                    break;

                case PDSAEncryptionType.TripleDES:
                    this.mCSP = new TripleDESCryptoServiceProvider();
                    break;
            }
            this.mCSP.GenerateKey();
            this.mCSP.GenerateIV();
        }

        public SymmetricAlgorithm CryptoProvider
        {
            get
            {
                return this.mCSP;
            }
            set
            {
                this.mCSP = value;
            }
        }

        public string EncryptedString
        {
            get
            {
                return this.mstrEncryptedString;
            }
            set
            {
                this.mstrEncryptedString = value;
            }
        }

        public PDSAEncryptionType EncryptionType
        {
            get
            {
                return this.mbytEncryptionType;
            }
            set
            {
                if (this.mbytEncryptionType != value)
                {
                    this.mbytEncryptionType = value;
                    this.mstrOriginalString = string.Empty;
                    this.mstrEncryptedString = string.Empty;
                    this.SetEncryptor();
                }
            }
        }

        public byte[] IV
        {
            get
            {
                return this.mCSP.IV;
            }
            set
            {
                this.mCSP.IV = value;
            }
        }

        public string IVString
        {
            get
            {
                return Convert.ToBase64String(this.mCSP.IV);
            }
            set
            {
                this.mCSP.IV = Convert.FromBase64String(value);
            }
        }

        public byte[] key
        {
            get
            {
                return this.mCSP.Key;
            }
            set
            {
                this.mCSP.Key = value;
            }
        }

        public string KeyString
        {
            get
            {
                return Convert.ToBase64String(this.mCSP.Key);
            }
            set
            {
                this.mCSP.Key = Convert.FromBase64String(value);
            }
        }

        public string OriginalString
        {
            get
            {
                return this.mstrOriginalString;
            }
            set
            {
                this.mstrOriginalString = value;
            }
        }

        public enum PDSAEncryptionType : byte
        {
            DES = 0,
            RC2 = 1,
            Rijndael = 2,
            TripleDES = 3
        }
    }
}